﻿
Imports osi.root.delegates
Imports osi.root.formation
Imports osi.root.procedure
Imports osi.root.utils
Imports osi.service.argument

Partial Public Class device_wrapper(Of T)
    Private Shared ReadOnly wta As unique_strong_map(Of String, vector(Of Func(Of var, T, pointer(Of T), event_comb)))
    Private Shared ReadOnly wa As vector(Of Func(Of var, T, pointer(Of T), event_comb))
    Private Shared ReadOnly wts As unique_strong_map(Of String, vector(Of _do_val_val_ref(Of var, T, T, Boolean)))
    Private Shared ReadOnly ws As vector(Of _do_val_val_ref(Of var, T, T, Boolean))

    Shared Sub New()
        wta = New unique_strong_map(Of String, vector(Of Func(Of var, T, pointer(Of T), event_comb)))()
        wa = New vector(Of Func(Of var, T, pointer(Of T), event_comb))()
        wts = New unique_strong_map(Of String, vector(Of _do_val_val_ref(Of var, T, T, Boolean)))()
        ws = New vector(Of _do_val_val_ref(Of var, T, T, Boolean))()
    End Sub

    Public Shared Function register(ByVal v As Func(Of var, T, pointer(Of T), event_comb)) As Boolean
        If v Is Nothing Then
            Return False
        Else
            wa.emplace_back(v)
            Return True
        End If
    End Function

    Public Shared Function register(ByVal type As String,
                                    ByVal v As Func(Of var, T, pointer(Of T), event_comb)) As Boolean
        If String.IsNullOrEmpty(type) OrElse
           v Is Nothing Then
            Return False
        Else
            wta.generate(type, Function() New vector(Of Func(Of var, T, pointer(Of T), event_comb))).emplace_back(v)
            Return True
        End If
    End Function

    Public Shared Function bind(ByVal type As String,
                                ByVal v As var,
                                ByRef o As Func(Of T, pointer(Of T), event_comb)) As Boolean
        If v Is Nothing Then
            Return False
        Else
            o = Function(i As T, p As pointer(Of T)) As event_comb
                    Return wrap(type, v, i, p)
                End Function
            Return True
        End If
    End Function

    Public Shared Function bind(ByVal v As var,
                                ByRef o As Func(Of String, T, pointer(Of T), event_comb)) As Boolean
        If v Is Nothing Then
            Return False
        Else
            o = Function(type As String, i As T, p As pointer(Of T)) As event_comb
                    Return wrap(type, v, i, p)
                End Function
            Return True
        End If
    End Function

    Public Shared Function bind(ByVal v As var,
                                ByRef o As Func(Of T, pointer(Of T), event_comb)) As Boolean
        If v Is Nothing Then
            Return False
        Else
            o = Function(i As T, p As pointer(Of T)) As event_comb
                    Return wrap(v, i, p)
                End Function
            Return True
        End If
    End Function

    Private Shared Function wrap(ByVal vs As vector(Of Func(Of var, T, pointer(Of T), event_comb)),
                                 ByVal v As var,
                                 ByVal i As T,
                                 ByVal o As pointer(Of T)) As event_comb
        assert(Not o Is Nothing)
        assert(Not vs Is Nothing)
        Dim j As Int32 = 0
        Dim ec As event_comb = Nothing
        Return New event_comb(Function() As Boolean
                                  If j = 0 Then
                                      assert(ec Is Nothing)
                                  Else
                                      assert(Not ec Is Nothing)
                                      If ec.end_result() Then
                                          i = (+o)
                                      Else
                                          Return False
                                      End If
                                  End If
                                  If j = vs.size() Then
                                      Return goto_end()
                                  Else
                                      ec = vs(j)(v, i, o)
                                      j += 1
                                      Return waitfor(ec)
                                  End If
                              End Function)
    End Function

    Public Shared Function wrap(ByVal type As String,
                                ByVal v As var,
                                ByVal i As T,
                                ByVal o As pointer(Of T)) As event_comb
        Dim ec As event_comb = Nothing
        Return New event_comb(Function() As Boolean
                                  o.renew()
                                  Dim vs As vector(Of Func(Of var, T, pointer(Of T), event_comb)) = Nothing
                                  If String.IsNullOrEmpty(type) OrElse
                                     Not wta.get(type, vs) Then
                                      Return eva(o, i) AndAlso
                                             goto_next()
                                  Else
                                      ec = wrap(vs, v, i, o)
                                      Return waitfor(ec) AndAlso
                                             goto_next()
                                  End If
                              End Function,
                              Function() As Boolean
                                  If ec.end_result_or_null() Then
                                      ec = wrap(wa, v, +o, o)
                                      Return waitfor(ec) AndAlso
                                             goto_next()
                                  Else
                                      Return False
                                  End If
                              End Function,
                              Function() As Boolean
                                  If ec.end_result() Then
                                      Dim r As T = Nothing
                                      If wrap(type, v, +o, r) Then
                                          Return eva(o, r) AndAlso
                                                 goto_end()
                                      Else
                                          Return False
                                      End If
                                  Else
                                      Return False
                                  End If
                              End Function)
    End Function

    Public Shared Function wrap(ByVal v As var,
                                ByVal i As T,
                                ByVal o As pointer(Of T)) As event_comb
        Dim ec As event_comb = Nothing
        Return New event_comb(Function() As Boolean
                                  o.renew()
                                  ec = wrap(wa, v, i, o)
                                  Return waitfor(ec) AndAlso
                                         goto_next()
                              End Function,
                              Function() As Boolean
                                  If ec.end_result() Then
                                      Dim r As T = Nothing
                                      If wrap(v, +o, r) Then
                                          Return eva(o, r) AndAlso
                                                 goto_end()
                                      Else
                                          Return False
                                      End If
                                  Else
                                      Return False
                                  End If
                              End Function)
    End Function

    Public Shared Function [erase](ByVal type As String) As Boolean
        Return wta.erase(type) OrElse
               wts.erase(type)
    End Function

    Public Shared Function [erase]() As Boolean
        Dim r As Boolean = False
        r = (Not wa.empty()) OrElse
            (Not ws.empty())
        wa.clear()
        ws.clear()
        Return r
    End Function

    Public Shared Sub clear()
        wta.clear()
        wa.clear()
        wts.clear()
        ws.clear()
    End Sub
End Class
